---
title: Methods
description: Explore Embla Carousel methods useful for extending the carousel beyond its native functionality.
order: 1
date: 2021-02-21
---

import { Tabs } from 'components/Tabs/Tabs'
import { TabsItem } from 'components/Tabs/TabsItem'
import { TABS_LIBRARY } from 'consts/tabs'

# Methods

Embla Carousel exposes a set of **useful methods** which makes it very **extensible**.

---

## Usage

You need an **initialized carousel** in order to **make use of methods**. They can be accessed during the lifecycle of a carousel and won't do anything after a carousel instance has been destroyed with the [destroy](/api/methods/#destroy) method.

### Calling methods

In the following example, the [slideNodes](/api/methods/#slidenodes) method is called and logged to the console as soon as the carousel has been initialized:

<Tabs groupId={TABS_LIBRARY.GROUP_ID}>
<TabsItem tab={TABS_LIBRARY.TABS.VANILLA}>

```js highlight={6}
import EmblaCarousel from 'embla-carousel'

const emblaNode = document.querySelector('.embla')
const emblaApi = EmblaCarousel(emblaNode)

console.log(emblaApi.slideNodes())
```

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.REACT}>

```jsx highlight={8}
import { useEffect } from 'react'
import useEmblaCarousel from 'embla-carousel-react'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = useEmblaCarousel()

  useEffect(() => {
    if (emblaApi) console.log(emblaApi.slideNodes())
  }, [emblaApi])

  // ...
}
```

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.VUE}>

```html highlight={8}
<script setup>
  import { onMounted } from 'vue'
  import emblaCarouselVue from 'embla-carousel-vue'

  const [emblaRef, emblaApi] = emblaCarouselVue()

  onMounted(() => {
    if (emblaApi.value) console.log(emblaApi.value.slideNodes())
  })

  // ...
</script>
```

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.SOLID}>

```jsx highlight={9}
import { onMount } from 'solid-js'
import createEmblaCarousel from 'embla-carousel-solid'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = createEmblaCarousel()

  onMount(() => {
    const api = emblaApi()
    if (api) console.log(api.slideNodes())
  })

  // ...
}
```

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.SVELTE}>

```html highlight={8}
<script>
  import emblaCarouselSvelte from 'embla-carousel-svelte'

  let emblaApi

  function onInit(event) {
    emblaApi = event.detail
    console.log(emblaApi.slideNodes())
  }
</script>

<div class="embla" use:emblaCarouselSvelte onemblaInit="{onInit}">...</div>
```

<Admonition type="note">
  **Note:** Starting with Svelte 5, the `on:` event handlers have been deprecated. However, `on:emblaInit` will remain for backward compatibility.
</Admonition>

</TabsItem>
</Tabs>

### TypeScript

The `EmblaCarouselType` is obtained directly from the **core package** `embla-carousel` and used like so:

<Tabs groupId={TABS_LIBRARY.GROUP_ID}>
<TabsItem tab={TABS_LIBRARY.TABS.VANILLA}>

```ts asLanguage=tsx highlight={1,6}
import EmblaCarousel, { EmblaCarouselType } from 'embla-carousel'

const emblaNode = document.querySelector('.embla')
const emblaApi = EmblaCarousel(emblaNode)

function logSlidesInView(emblaApi: EmblaCarouselType): void {
  console.log(emblaApi.slidesInView())
}

emblaApi.on('slidesInView', logSlidesInView)
```

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.REACT}>

```tsx highlight={2,8}
import React, { useCallback } from 'react'
import { EmblaCarouselType } from 'embla-carousel'
import useEmblaCarousel from 'embla-carousel-react'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = useEmblaCarousel()

  const logSlidesInView = useCallback((emblaApi: EmblaCarouselType) => {
    console.log(emblaApi.slidesInView())
  }, [])

  useEffect(() => {
    if (emblaApi) emblaApi.on('slidesInView', logSlidesInView)
  }, [emblaApi, logSlidesInView])

  // ...
}
```

<Admonition type="warning">
  If you're using `pnpm`, you need to install `embla-carousel` as a
  **devDependency** when importing types from it like demonstrated above.
  <br />
  This is because even though `embla-carousel-react` has `embla-carousel` as a
  dependency, `pnpm` makes nested dependencies inaccessible by design.
</Admonition>

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.VUE}>

```html highlight={3,8}
<script setup lang="ts">
  import { onMounted } from 'vue'
  import { EmblaCarouselType } from 'embla-carousel'
  import emblaCarouselVue from 'embla-carousel-vue'

  const [emblaRef] = emblaCarouselVue()

  function logSlidesInView(emblaApi: EmblaCarouselType): void {
    console.log(emblaApi.slidesInView())
  }

  onMounted(() => {
    if (emblaApi.value) emblaApi.value.on('slidesInView', logSlidesInView)
  })

  // ...
</script>
```

<Admonition type="warning">
  If you're using `pnpm`, you need to install `embla-carousel` as a
  **devDependency** when importing types from it like demonstrated above.
  <br />
  This is because even though `embla-carousel-vue` has `embla-carousel` as a
  dependency, `pnpm` makes nested dependencies inaccessible by design.
</Admonition>

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.SOLID}>

```jsx highlight={2,8}
import { onMount } from 'solid-js'
import { EmblaCarouselType } from 'embla-carousel'
import createEmblaCarousel from 'embla-carousel-solid'

export function EmblaCarousel() {
  const [emblaRef, emblaApi] = createEmblaCarousel()

  function logSlidesInView(emblaApi: EmblaCarouselType): void {
    console.log(emblaApi.slidesInView())
  }

  onMount(() => {
    const api = emblaApi()
    if (api) api.on('slidesInView', logSlidesInView)
  })

  // ...
}
```

<Admonition type="warning">
  If you're using `pnpm`, you need to install `embla-carousel` as a
  **devDependency** when importing types from it like demonstrated above.
  <br />
  This is because even though `embla-carousel-solid` has `embla-carousel` as a
  dependency, `pnpm` makes nested dependencies inaccessible by design.
</Admonition>

</TabsItem>
<TabsItem tab={TABS_LIBRARY.TABS.SVELTE}>

```html highlight={2,5,7}
<script>
  import { EmblaCarouselType } from 'embla-carousel'
  import emblaCarouselSvelte from 'embla-carousel-svelte'

  let emblaApi: EmblaCarouselType

  function logSlidesInView(emblaApi: EmblaCarouselType): void {
    console.log(emblaApi.slidesInView())
  }

  function onInit(event: CustomEvent<EmblaCarouselType>): void {
    emblaApi = event.detail
    emblaApi.on('slidesInView', logSlidesInView)
  }
</script>

<div class="embla" use:emblaCarouselSvelte onemblaInit="{onInit}">...</div>
```

<Admonition type="note">
  **Note:** Starting with Svelte 5, the `on:` event handlers have been deprecated. However, `on:emblaInit` will remain for backward compatibility.
</Admonition>

<Admonition type="warning">
  If you're using `pnpm`, you need to install `embla-carousel` as a
  **devDependency** when importing types from it like demonstrated above.
  <br />
  This is because even though `embla-carousel-svelte` has `embla-carousel` as a
  dependency, `pnpm` makes nested dependencies inaccessible by design.
</Admonition>

</TabsItem>
</Tabs>

## Reference

Below follows an exhaustive **list of all** Embla Carousel **methods** with their respective parameters and return values.

---

### rootNode

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`HTMLElement`</BrandSecondaryText>

Get the root node that holds the scroll container with slides inside. This method can be useful when you need to manipulate the root element dynamically or similar.

---

### containerNode

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`HTMLElement`</BrandSecondaryText>

Get the container node that holds the slides. This method can be useful when you need to manipulate the container element dynamically or similar.

---

### slideNodes

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`HTMLElement[]`</BrandSecondaryText>

Get all the slide nodes inside the container. This method can be useful when you need to manipulate the slide elements dynamically or similar.

---

### scrollNext

Parameters: <BrandPrimaryText>`jump?: boolean`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

Scroll to the next snap point if possible. When [loop](/api/options/#loop) is disabled and the carousel has reached the last snap point, this method won't do anything. Set the **jump** parameter to `true` when you want to go to the next slide instantly.

---

### scrollPrev

Parameters: <BrandPrimaryText>`jump?: boolean`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

Scroll to the previous snap point if possible. When [loop](/api/options/#loop) is disabled and the carousel has reached the first snap point, this method won't do anything. Set the **jump** parameter to `true` when you want to go to the previous slide instantly.

---

### scrollTo

Parameters: <BrandPrimaryText>`index: number`, `jump?: boolean`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

Scroll to a snap point by its unique index. If [loop](/api/options/#loop) is enabled, Embla Carousel will choose the closest way to the target snap point. Set the **jump** parameter to `true` when you want to go to the desired slide instantly.

---

### canScrollNext

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`boolean`</BrandSecondaryText>

Check the possiblity to scroll to a next snap point. If [loop](/api/options/#loop) is enabled and the container holds any slides, this will always return `true`.

---

### canScrollPrev

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`boolean`</BrandSecondaryText>

Check the possiblity to scroll to a previous snap point. If [loop](/api/options/#loop) is enabled and the container holds any slides, this will always return `true`.

---

### selectedScrollSnap

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`number`</BrandSecondaryText>

Get the index of the selected snap point.

---

### previousScrollSnap

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`number`</BrandSecondaryText>

Get the index of the previously selected snap point.

---

### scrollSnapList

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`number[]`</BrandSecondaryText>

Get an array containing all the snap point positions. Each position represents how far the carousel needs to progress in order to reach this position.

---

### scrollProgress

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`number`</BrandSecondaryText>

Check how far the carousel has scrolled of its scrollable length from 0 - 1. For example, **0.5 equals 50%**. For example, this can be useful when creating a scroll progress bar.

---

### slidesInView

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`number[]`</BrandSecondaryText>

Get slide indexes **visible** in the carousel viewport. Honors the [inViewThreshold](/api/options/#inviewthreshold) option.

---

### slidesNotInView

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`number[]`</BrandSecondaryText>

Get slide indexes **not visible** in the carousel viewport. Honors the [inViewThreshold](/api/options/#inviewthreshold) option.

---

### internalEngine

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`EmblaEngineType`</BrandSecondaryText>

Exposes almost all internal functionality used by Embla. Useful when creating plugins or similar.

<Admonition type="note">
  **Note:** Please **refrain** from creating **bug reports** related to this
  method. If you're using this and running into problems, it's a 99.8% chance
  that you don't understand how this works. Use at your own risk.
</Admonition>

---

### reInit

Parameters: <BrandPrimaryText>`options?: EmblaOptionsType`, `plugins?: EmblaPluginType[]`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

Hard reset the carousel after it has been initialized. This method allows for changing [options](/api/options/) and [plugins](/api/plugins/) after initializing a carousel.

<Admonition type="note">
  **Note:** Passed options will be **merged** with current options, but passed
  plugins will **replace** current plugins.
</Admonition>

---

### plugins

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`EmblaPluginsType`</BrandSecondaryText>

Returns an object with key value pairs where the keys are the plugin names, and the plugin API:s are the values.

---

### destroy

Parameters: <BrandPrimaryText>`none`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

Destroy the carousel instance permanently. This is a one way operation and is intended to be used as a cleanup measure when the carousel instance isn't needed anymore.

---

### on

Parameters: <BrandPrimaryText>`event: EmblaEventType`, `callback: (emblaApi: EmblaCarouselType, eventName: EmblaEventType) => void`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

**Subscribe** to an Embla specific [event](/api/events/) with a **callback**. Added event listeners will persist even if [reInit](/api/methods/#reinit) is called, either until the carousel is destroyed or the event is removed with the [off](/api/methods/#off) method.

---

### off

Parameters: <BrandPrimaryText>`event: EmblaEventType`, `callback: (emblaApi: EmblaCarouselType, eventName: EmblaEventType) => void`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

**Unsubscribe** from an Embla specific [event](/api/events/). Make sure to pass the **same callback reference** when the callback was added with the [on](/api/methods/#on) method.

---

### emit

Parameters: <BrandPrimaryText>`event: EmblaEventType`</BrandPrimaryText>  
Returns: <BrandSecondaryText>`void`</BrandSecondaryText>

Emits an embla [event](/api/events/). This doesn't trigger any internal Embla functionality.

---
